<?php

namespace addons\yunfood\controller;

use addons\epay\library\Service;
use addons\yunfood\library\Logic;
use addons\yunfood\model\Config;
use addons\yunfood\model\FundOrder;
use addons\yunfood\model\Order;
use addons\yunfood\model\Payment;
use addons\yunfood\model\UserAuth;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\Log;
use think\Session;

/**
 * 通知
 */
class Web extends \think\addons\Controller
{
    protected $noNeedLogin = ['*'];
    protected $layout = '';

    public function wechatCallback()
    {
        if ($this->payCallback('wechat')) {
            echo 'success';
        }

        return;
    }

    public function alipayCallback()
    {
        if ($this->payCallback('alipay')) {
            echo 'success';
        }

        return;
    }

    private function payCallback($channel)
    {
        if (! $pay = Service::checkNotify($channel)) {
            Log::write('签名错误', 'error');

            return false;
        }
        $data = $pay->verify();
        $payAmount = $data['total_fee'] / 100;
        $tradeNo = $data['out_trade_no'];
        try {
            $this->payFinish($tradeNo, $payAmount);
        } catch (Exception $e) {
            if ($e->getMessage() === '已支付成功') {
                return false;
            }
        }

        return true;
    }

    // 支付回调
    private function payFinish($tradeNo, $payAmount)
    {
        // 开启事务
        Db::startTrans();
        try {
            if (! $payment = Payment::where('trade_no', $tradeNo)->lock(true)->find()) {
                throw new Exception('支付信息不存在');
            }
            if ($payment->status == Payment::STATUS_DONE) {
                throw new Exception('已支付成功');
            }
            $payment->finish_time = time();
            $payment->status = Payment::STATUS_DONE;
            $payment->save();

            if ($payment->order_type === Payment::ORDER_TYPE_GOODS) {
                Order::finishOrder($payment->order_no, $payment->goods_amount, $payment->channelText);
            } elseif ($payment->order_type === Payment::ORDER_TYPE_FUND) {
                FundOrder::finishOrder($payment->order_no, $payment->goods_amount, $payment->channelText);
            }
            Db::commit();
        } catch (PDOException | Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
    }

    public function connect()
    {
        $url = $this->request->request('url', $this->request->server('HTTP_REFERER', '/', 'trim'), 'trim');
        if (! $url) {
            $this->error('参数错误');
        }
        Session::set('redirectUrl', $url);

        // 跳转到登录授权页面
        $state = md5(uniqid(rand(), true));
        Session::set('state', $state);
        $params = [
            'appid'         => Config::getGroupAttribute(Config::GROUP_MP, 'app_id'),
            'redirect_uri'  => addon_url('yunfood/web/callback', [], false, true),
            'response_type' => 'code',
            'scope'         => 'snsapi_base',
            'state'         => $state,
        ];
        $authUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize';
        $authUrl .= '?' . http_build_query($params) . '#wechat_redirect';
        $this->redirect($authUrl);
    }

    public function callback()
    {
        $code = $this->request->get('code');
        if (! $code) {
            $this->error('code不能为空');
        }
        if (isset($params['state']) && $params['state'] != Session::get('state')) {
            $this->error('state不正确');
        }
        $userInfo = Logic::getMpCodeData($code);

        // 成功后返回之前页面
        $url = Session::has('redirectUrl') ? Session::pull('redirectUrl') : '';
        if (! $url) {
            $this->error('没有跳转地址');
        }
        $authKey = Logic::getUserAuthKey($userInfo['openid'], UserAuth::SOURCE_MP);
        $url .= (strpos($url, '?') !== false ? '&' : '?') . 'auth_key=' . $authKey;
        $this->redirect($url);
    }
}
